package com.ai.bitcoin.schedule.task;

import com.ai.bitcoin.constant.Bcc;
import com.ai.bitcoin.jpa.entity.*;
import com.ai.bitcoin.jpa.service.*;
import com.ai.bitcoin.redis.service.BccRedisService;
import com.ai.bitcoin.serialize.BeanSerial;
import com.ai.bitcoin.utils.MathUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author Jason
 * @date 2018.5.11
 **/
@Service
@Slf4j
public class ReportTask extends AbstractTask {
    @Autowired
    BccBasicInfoService bccBasicInfoService;
    @Autowired
    BccReportService bccReportService;
    @Autowired
    BccReportHisService bccReportHisService;
    @Autowired
    BccRedisService bccRedisService;
    @Autowired
    BccPriceInfoService bccPriceInfoService;
    @Autowired
    BccNewsService bccNewsService;
    private SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public void execute() {
        List<BccBasicInfo> basicInfoList = bccBasicInfoService.findByRecordState(Bcc.RecordState.PUBLISH);
        for (BccBasicInfo bccBasicInfo : basicInfoList) {
            BccReport bccReport = getInitBccReport(bccBasicInfo);
            bccReportService.save(bccReport);
        }

        List<BccReport> list = bccReportService.findAllByOrderByCirculationCapUsdDesc();
        double[] cap = new double[list.size()];
        double[] supply = new double[list.size()];

        for (int i = 0; i < list.size(); i++) {
            BccReport bccReport = list.get(i);
            bccReport.setRankCirculationCap(i + 1);
            cap[i] = getDouble(bccReport.getCirculationCapUsd());
            supply[i] = getDouble(bccReport.getCirculationSupply());
        }
        double capTotal = MathUtil.sum(cap);
        double supplyTotal = MathUtil.sum(supply);

        list = bccReportService.findOrderByVolume24hDesc();
        for (int i = 0; i < list.size(); i++) {
            BccReport bccReport = list.get(i);
            bccReport.setRankVolume24h(i + 1);
            bccReport.setCapPercent(getPercent(getDouble(bccReport.getCirculationCapUsd()), capTotal));
            bccReport.setSupplyPercent(getPercent(getDouble(bccReport.getCirculationSupply()), supplyTotal));
            bccReportService.save(bccReport);
            bccRedisService.cacheReportDetail2Redis(bccReport.getBccId(), BeanSerial.Bean2Json(bccReport));
        }
        //24h涨跌幅
        mv2His();

        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        Pageable pageable = PageRequest.of(0, 5, sort);
        List<BccNews> listNews = bccNewsService.findAll(pageable);
        for (BccNews news : listNews) {
            bccRedisService.cacheNews(news.getId(), BeanSerial.Bean2Json(news));
            try {
                Thread.sleep(100);
            } catch (Exception ignored) {
            }
        }
        JSONArray digestNewsJ = new JSONArray();
        for (BccNews bccNews : listNews) {
            bccNews.setDescription(getDigest(bccNews.getDescription()));
            digestNewsJ.add(BeanSerial.Bean2Json(bccNews));
        }
        bccRedisService.cacheDigestNews(digestNewsJ);

    }

    private double getDouble(String value) {
        if (StringUtils.isEmpty(value))
            return 0;
        else return Double.valueOf(value);
    }

    private float getPercent(double value, double base) {
        if (base == 0)
            return 0;
        else
            return (float) (value / base);

    }

    private void mv2His() {
        String date = dateFormater.format(new Date());
        List<BccReport> list = bccReportService.findByReportDateNot(date);
        for (BccReport aList : list) {
            BccReportHis bccReportHis = new BccReportHis();
            BeanUtils.copyProperties(aList, bccReportHis);
            bccReportHisService.save(bccReportHis);
        }
        bccReportService.deleteByReportDateNot(date);
    }

    private BccReport getInitBccReport(BccBasicInfo bccBasicInfo) {
        BccReport bccReport = new BccReport();
        bccReport.setBccId(bccBasicInfo.getBccId());
        bccReport.setNameCn(bccBasicInfo.getNameCn());
        bccReport.setNameEn(bccBasicInfo.getNameEn());
        bccReport.setMarketCount("0");
        bccReport.setWhitepaperUrl(bccBasicInfo.getWhitepaperUrl());
        bccReport.setOfficialSiteUrl(bccBasicInfo.getOfficialSiteUrl());
        bccReport.setBlockViewSiteUrl(bccBasicInfo.getBlockViewSiteUrl());
        bccReport.setTokenPlatform("");//bccBasicInfo token_platform
        bccReport.setIcoPriceUsd("");
        bccReport.setIcoPriceCny("");
        bccReport.setIcoPriceBtc("");
        bccReport.setIcoTime(bccBasicInfo.getIcoStartTime());

        bccReport.setCapPercent(0);
        bccReport.setSupplyPercent(0);
        bccReport.setTurnoverPercent(0);
        bccReport.setReportDate(dateFormater.format(new Date()));

        List<BccPriceInfo> list = bccPriceInfoService.findByBccIdAndRecordState(bccReport.getBccId(), Bcc.RecordState.PUBLISH);
        if (list.size() > 0) {
            BccPriceInfo bccPriceInfo = list.get(0);
            bccReport.setLow1dUsd(bccPriceInfo.getLow1dUsd());
            bccReport.setLow1dCny(bccPriceInfo.getLow1dCny());
            bccReport.setLow1dBtc(bccPriceInfo.getLow1dBtc());
            bccReport.setHigh1dUsd(bccPriceInfo.getHigh1dUsd());
            bccReport.setHigh1dCny(bccPriceInfo.getHigh1dCny());
            bccReport.setHigh1dBtc(bccPriceInfo.getHigh1dBtc());
            bccReport.setPriceUsdChange1d(bccPriceInfo.getChange1d());
        }

        return bccReport;
    }

    private String getDigest(String content) {
        if (StringUtils.isEmpty(content))
            return "";
        else {
            int len = content.length();
            if (len > 100) {
                return content.substring(0, 100);
            }
            else {
                return content;
            }

        }
    }

}
